﻿using System;
using System.Collections.Generic;
using System.Linq;
using Model.Repositories;
using DomenModel;
using System.Data.Entity;
using System.Linq.Expressions;
using Model.Repositories.Interfaces;
using System.Data;

namespace Infrastructure.Repositories
{
    public class ItemRepo: IItemCrud
    {
        
        public Item GetById(long Id)
        {
            using (GeneralContext _db = new GeneralContext())
            {
                Item itemById = _db.Items.FirstOrDefault(p => p.ItemId == Id && p.IsActive == true);
                return itemById;
            }
        }
       
        public Item GetByName(string name)
        {
            using (GeneralContext _db = new GeneralContext())
            {
                Item itemByName = _db.Items.FirstOrDefault(p => p.Name == name && p.IsActive == true);
                return itemByName;
            } 
        }

        

        public void Save(Item t)
        {
            using (GeneralContext _db = new GeneralContext())
            {

                _db.Items.Add(t);
                _db.SaveChanges();
            }
        }

        public void Update(Item t)
        {
            using (GeneralContext _db = new GeneralContext())
            {
                Item itemById = _db.Items.FirstOrDefault(p => p.ItemId == t.ItemId && p.IsActive == true );
                itemById.Name = t.Name;
                itemById.Description = t.Description;
                itemById.ItemPrice = t.ItemPrice;
                itemById.IsActive = t.IsActive;
                _db.Entry(itemById).State = EntityState.Modified;
                _db.SaveChanges();
            }


        }

        public void Delete(long Id)
        {
            using (GeneralContext _db = new GeneralContext())
            {
                Item itemById = _db.Items.FirstOrDefault(p => p.ItemId == Id);
                _db.Items.Remove(itemById);
                _db.SaveChanges();
            }
        }

        public void Deactivate(string Name)
        {
            using (GeneralContext _db = new GeneralContext())
            {
                Item itemForRemove = _db.Items.FirstOrDefault(p => p.Name == Name);
                itemForRemove.IsActive = false;
                _db.Entry(itemForRemove).State = EntityState.Modified;
                _db.SaveChanges();
            }

        }

        public void DeactivateById(int id)
        {
            using (GeneralContext _db = new GeneralContext())
            {
                Item itemForRemove = _db.Items.FirstOrDefault(p => p.ItemId == id);
                itemForRemove.IsActive = false;
                _db.Entry(itemForRemove).State = EntityState.Modified;
                _db.SaveChanges();
            }

        } 

        public List<Item> GetCollection()
        {
            using (GeneralContext _db = new GeneralContext())
            {
                var listOfItem = _db.Items.ToList();
                return listOfItem;
            }
        }


        public List<Item> GetListForPaginationWithFilter(int page, int itemsOnPage, Expression<Func<Item, bool>> predicateListSelectedField, Expression<Func<Item, string>> predicateSortBy, bool descending)
        {
            using (GeneralContext _db = new GeneralContext())
            {

                    if (descending == true)
                    {
                        var listForPagination = _db.Items.Include("ItemDimensions")
                            .OrderByDescending(predicateSortBy)
                           .Where(predicateListSelectedField.Compile())
                            .Where(p => p.IsActive == true)
                            .Skip((page - 1) * itemsOnPage)
                            .Take(itemsOnPage)
                            .ToList();

                        return listForPagination;
                    }
                    else
                    {
                        var listForPagination = _db.Items.Include("ItemDimensions")
                            .OrderBy(predicateSortBy)
                           .Where(predicateListSelectedField.Compile())
                            .Where(p => p.IsActive == true)
                            .Skip((page - 1) * itemsOnPage)
                            .Take(itemsOnPage)
                            .ToList();

                        return listForPagination;
                    }

            }
        }

        public List<Item> GetListForPagination(int page, int itemsOnPage, Expression<Func<Item, string>> predicate, bool descending)
        {
            using (GeneralContext _db = new GeneralContext())
            {

                    if (descending == true)
                    {
                        var listForPagination = _db.Items.Include("ItemDimensions")
                            .OrderByDescending(predicate)
                            .Where(p => p.IsActive == true)
                            .Skip((page - 1) * itemsOnPage)
                            .Take(itemsOnPage)
                            .ToList();

                        return listForPagination;
                    }
                    else
                    {
                        var listForPagination = _db.Items
                         .Include("ItemDimensions")
                         .OrderBy(predicate)
                          .Where(p => p.IsActive == true)
                          .Skip((page - 1) * itemsOnPage)
                          .Take(itemsOnPage)
                           .ToList();

                        return listForPagination;
                    }

            }
        }


        public long GetCountOfItems()
        {
            using (GeneralContext _db = new GeneralContext())
            {
                long _i = _db.Items.Where(p => p.IsActive == true).Count();
                return _i;
            }

        }

        public long GetCountOfItems(Expression<Func<Item, bool>> predicate)
        {
            using (GeneralContext _db = new GeneralContext())
            {
                long _i = _db.Items.Where(predicate).Where(p => p.IsActive == true).Count();
                return _i;
            }
        }

        public List<Item> GetListForItemPagination(string sortBy)
        {
            using (GeneralContext _db = new GeneralContext())
            {
                List<Item> listOfItem;
                switch (sortBy)
                {
                    case "Name desc":
                        listOfItem = _db.Items.OrderByDescending(p => p.Name).ToList();
                        break;
                    case "Description":
                        listOfItem = _db.Items.OrderBy(p => p.Description).ToList();
                        break;
                    case "Description desc":
                        listOfItem = _db.Items.OrderByDescending(p => p.Description).ToList(); ;
                        break;
                    default:
                        listOfItem = _db.Items.OrderBy(p => p.Name).ToList();
                        break;
                }

                return listOfItem;
            }
        }

        public List<Item> GetListForItemPagination(string sortBy, string searchString)
        {
            using (GeneralContext _db = new GeneralContext())
            {
                List<Item> listOfItem;
                switch (sortBy)
                {
                    case "Name desc":
                        listOfItem = _db.Items.OrderByDescending(p => p.Name).Where(c => c.Name.Contains(searchString)).ToList();
                        break;
                    case "Description":
                        listOfItem = _db.Items.OrderBy(p => p.Description).Where(c => c.Name.Contains(searchString)).ToList();
                        break;
                    case "Description desc":
                        listOfItem = _db.Items.OrderByDescending(p => p.Description).Where(c => c.Name.Contains(searchString)).ToList(); ;
                        break;
                    default:
                        listOfItem = _db.Items.OrderBy(p => p.Name).Where(c => c.Name.Contains(searchString)).ToList();
                        break;
                }

                return listOfItem;
            }
        }

    }
}
